依存関係フローグラフの例
次の例では、A-E の 5 つの計算が下記の 「単純な依存関係グラフ」 のように半順序でセットアップされています。フローグラフの各エッジで、エッジの最後のノードは先頭のノードが開始する前に実行を完了していなければなりません。

単純な依存関係グラフ
#include <cstdio>
#include "oneapi/tbb/flow_graph.h"
using namespace oneapi::tbb::flow;
struct body {
std::string my_name;
body(const char *name) : my_name(name) {}
void operator()(continue_msg) const {
printf("%s\n", my_name.c_str());
}
};
int main() {
graph g;
broadcast_node< continue_msg > start(g);
continue_node<continue_msg> a(g, body("A"));
continue_node<continue_msg> b(g, body("B"));
continue_node<continue_msg> c(g, body("C"));
continue_node<continue_msg> d(g, body("D"));
continue_node<continue_msg> e(g, body("E"));
make_edge(start, a);
make_edge(start, b);
make_edge(a, c);
make_edge(b, c);
make_edge(c, d);
make_edge(a, e);
for (int i = 0; i < 3; ++i) {
start.try_put(continue_msg());
g.wait_for_all();
}
return 0;
}この例では、ノード A-E がそれぞれの名前を出力します。そのため、これらのノードはすべて struct body を使用してボディー・オブジェクトを構築できます。
main 関数で、フローグラフは一回セットアップされ、3 回実行されます。この例のノードはすべて、continue_msg オブジェクトを使用します。このタイプは、ノードが実行完了したことを通知するために使用されます。
main 関数の最初の行は、graph オブジェクト g をインスタンス化します。次の行で、start という名称の broadcast_node を作成しています。このノードに渡されるものはすべて、その後続 (サクセサー) にブロードキャストされます。start ノードは、main の最後にある for ループで残りのフローグラフを実行するために使用されます。
この例では、名前が a - e の 5 つの continue_node オブジェクトが作成されます。各ノードは、graph g への参照と、実行時に呼び出す関数オブジェクトにより構築されます。後続 (サクセサー) / 先行 (プリディセッサー) の関係は、ノードの宣言に続く make_edge 呼び出しでセットアップされます。
ノードとエッジが設定された後、for ループのそれぞれの反復で try_put によって、a と b の両方に continue_msg がブロードキャストされます。a と b のどちらも単一の continue_msg を持っています。これは、どちらも先行する start しか持たないためです。
start からメッセージを受け取ると、ボディー・オブジェクトを実行します。完了すると、それぞれがサクセサーにメッセージを転送します。計算を並列に実行可能な場合、グラフは複数のタスクを使用してノード間でメッセージを送る処理と、ノードのボディーを実行する処理を並列に実行します。
参照:
